package cn.wolfcode.service.impl;

import cn.wolfcode.domain.AccountTransaction;
import cn.wolfcode.domain.OperateIntegralVo;
import cn.wolfcode.mapper.AccountTransactionMapper;
import cn.wolfcode.mapper.UsableIntegralMapper;
import cn.wolfcode.service.IUsableIntegralService;
import io.seata.rm.tcc.api.BusinessActionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

/**
 * Created by lanxw
 */
@Service
public class UsableIntegralServiceImpl implements IUsableIntegralService {
    @Autowired
    private UsableIntegralMapper usableIntegralMapper;
    @Autowired
    private AccountTransactionMapper accountTransactionMapper;

    @Override
    @Transactional
    public int decrIntegral(OperateIntegralVo vo) {
        return usableIntegralMapper.decrIntegral(vo.getUserId(),vo.getValue());
    }

    @Override
    @Transactional
    public void addIntegral(OperateIntegralVo vo) {
        usableIntegralMapper.incrIntegral(vo.getUserId(),vo.getValue());
    }

    @Override
    @Transactional
    public int decrIntegralTry(OperateIntegralVo vo, BusinessActionContext context) {
        System.out.println("执行TRY方法");
        //1.插入事务事务
        AccountTransaction transaction = new AccountTransaction();
        transaction.setTxId(context.getXid());//全局事务ID
        transaction.setActionId(context.getBranchId());//分支事务ID
        transaction.setUserId(vo.getUserId());//用户ID
        transaction.setAmount(vo.getValue());//积分数量
        Date now = new Date();
        transaction.setGmtCreated(now);

        accountTransactionMapper.insert(transaction);transaction.setGmtModified(now);
        //2.执行业务逻辑
        return usableIntegralMapper.freezeIntegral(vo.getUserId(),vo.getValue());
    }

    @Override
    @Transactional
    public void decrIntegralCommit(BusinessActionContext context) {
        System.out.println("执行Commit方法");
        //1.查询事务日志记录
        AccountTransaction transaction = accountTransactionMapper.get(context.getXid(), context.getBranchId());
        if(transaction!=null){
            if(AccountTransaction.STATE_TRY==transaction.getState()){
                //2.将记录修改成Commit状态
                int effectCount = accountTransactionMapper.updateAccountTransactionState(context.getXid(), context.getBranchId(), AccountTransaction.STATE_COMMIT, AccountTransaction.STATE_TRY);
                if(effectCount>0){
                    //3.执行业务逻辑
                    usableIntegralMapper.commitChange(transaction.getUserId(),transaction.getAmount());
                }
            }
        }else{
            //通知管理员
        }

    }
    @Override
    @Transactional
    public void decrIntegralRollback(BusinessActionContext context) {
        System.out.println("执行Cancel方法");
        //1.查询事务日志记录
        AccountTransaction transaction = accountTransactionMapper.get(context.getXid(), context.getBranchId());
        //2.如果有记录(执行过TRY)
        if(transaction!=null){
            //      - 判断状态是否为TRY
            if(AccountTransaction.STATE_TRY==transaction.getState()){

                int effectCount = accountTransactionMapper.updateAccountTransactionState(context.getXid(), context.getBranchId(), AccountTransaction.STATE_CANCEL, AccountTransaction.STATE_TRY);
                if(effectCount>0){
                    //           - 执行Cancel逻辑
                    usableIntegralMapper.unFreezeIntegral(transaction.getUserId(),transaction.getAmount());
                }
            }
        }else{
            OperateIntegralVo vo = (OperateIntegralVo) context.getActionContext("vo");
            //3.如果没有记录(没有执行TRY)
            //      - 插入记录
            transaction = new AccountTransaction();
            transaction.setTxId(context.getXid());//全局事务ID
            transaction.setActionId(context.getBranchId());//分支事务ID
            transaction.setUserId(vo.getUserId());//用户ID
            transaction.setAmount(vo.getValue());//积分数量
            Date now = new Date();
            transaction.setGmtCreated(now);
            transaction.setGmtModified(now);
            transaction.setState(AccountTransaction.STATE_CANCEL);
            accountTransactionMapper.insert(transaction);
        }
    }
}
